package com.gainloop.Api;

import java.util.ArrayList;

import org.alexd.jsonrpc.JSONRPCException;
import org.json.JSONArray;
import org.json.JSONException;

import com.gainloop.Api.Entity.Session;
import com.gainloop.Api.Entity.User;
import com.gainloop.Api.Entity.Wish;
import com.gainloop.Api.Entity.Tag;
import com.gainloop.Api.Entity.WishEx;
import com.gainloop.Data.Registry;

/**
 * @author owner
 * 
 */
public class Wishes extends ApiAbstract {
	
	public enum SearchType {
		NORMAL,
		FRIENDS_ONLY
	};
	
	static private Wishes _instance = null;
	
	public static Wishes getInstance()
	{
		if(_instance == null) {
			_instance = new Wishes();
		}
		
		return _instance;
	}

	public ApiResponseObject<Wish> create(Wish wish, ArrayList<Tag> tags)
			throws JSONRPCException {
		if (wish.getId() != 0) {
			throw new ApiException("wish id must not set");
		}

		JSONArray tagsIds = new JSONArray();
		for (Tag tag : tags) {
			tagsIds.put(tag.getId());
		}

		try {
			return new ApiResponseObject<Wish>(GetClient().callJSONObject(
					"wishes.create", wish.toObject(), tagsIds), Wish.class);
		} catch (JSONException e) {
			throw new ApiException("invalid respond");
		}
	}

	public ApiResponseObject<Wish> getById(long id) throws JSONRPCException {

		try {
			return new ApiResponseObject<Wish>(GetClient().callJSONObject(
					"wishes.getById", id), Wish.class);
		} catch (JSONException e) {
			throw new ApiException("invalid respond");
		}
	}

	public ArrayList<WishEx> getTopWishes(int page) throws JSONRPCException {
		return getTopWishes(page, 10);
	}

	public ArrayList<WishEx> getTopWishes(int page, int pageLimit)
			throws JSONRPCException {
		if (pageLimit < 1 || pageLimit > 25) {
			throw new ApiException("invalid pageLimit");
		}
		if (page < 1 || page > 50) {
			throw new ApiException("invalid page");
		}

		try {
			ApiResponseArray<WishEx> res = new ApiResponseArray<WishEx>(GetClient().callJSONObject(
					"wishes.getTopWishes", page, pageLimit), WishEx.class);
			
			if(res.getReturnCode() != 0) {
				throw new ApiException("wrong usage: ", res);
			}
			
			return res.getData();
			
		} catch (JSONException e) {
			throw new ApiException("invalid respond: " + e.getMessage());
		}
	}

	public ArrayList<WishEx> getRecentWishes(int page) throws JSONRPCException {
		return getRecentWishes(page, 10);
	}

	public ArrayList<WishEx> getRecentWishes(int page, int pageLimit)
			throws JSONRPCException {
		if (pageLimit < 1 || pageLimit > 25) {
			throw new ApiException("invalid pageLimit");
		}
		if (page < 1 || page > 50) {
			throw new ApiException("invalid page");
		}

		try {
			ApiResponseArray<WishEx> res =  new ApiResponseArray<WishEx>(GetClient().callJSONObject(
					"wishes.getRecentWishes", page, pageLimit), WishEx.class);
			
			if(res.getReturnCode() != 0) {
				throw new ApiException("wrong usage: ", res);
			}
			
			return res.getData();
		} catch (JSONException e) {
			throw new ApiException("invalid respond");
		}
	}

	public ArrayList<WishEx> getFriendsWishes(int page) throws JSONRPCException {
		return getFriendsWishes(page, 10);
	}

	public ArrayList<WishEx> getFriendsWishes(int page, int pageLimit)
			throws JSONRPCException {
		Session session = Registry.GetSession();
		if(session == null) {
			throw new ApiException("invalid session");
		}
		
		if (pageLimit < 1 || pageLimit > 25) {
			throw new ApiException("invalid pageLimit");
		}
		if (page < 1 || page > 50) {
			throw new ApiException("invalid page");
		}

		try {
			ApiResponseArray<WishEx> res =  new ApiResponseArray<WishEx>(GetClient().callJSONObject(
					"wishes.getFriendsWishes", session.toObject(), page, pageLimit), WishEx.class);
			
			if(res.getReturnCode() != 0) {
				throw new ApiException("wrong usage: ", res);
			}
			
			return res.getData();
		} catch (JSONException e) {
			throw new ApiException("invalid respond");
		}
	}

	public ArrayList<WishEx> getUserWishes(User user, int page) throws JSONRPCException {
		return getUserWishes(user, page, 10);
	}

	public ArrayList<WishEx> getUserWishes(User user, int page, int pageLimit)
			throws JSONRPCException {
		if (pageLimit < 1 || pageLimit > 25) {
			throw new ApiException("invalid pageLimit");
		}
		if (page < 1 || page > 50) {
			throw new ApiException("invalid page");
		}

		try {
			ApiResponseArray<WishEx> res =  new ApiResponseArray<WishEx>(GetClient().callJSONObject(
					"wishes.getUserWishes", user.getId(), page, pageLimit), WishEx.class);
			
			if(res.getReturnCode() != 0) {
				throw new ApiException("wrong usage: ", res);
			}
			
			return res.getData();
		} catch (JSONException e) {
			throw new ApiException("invalid respond");
		}
	}
	
	public ArrayList<WishEx> search(Long categoryId, ArrayList<Tag> tags, SearchType type, int page) throws JSONRPCException
	{
		return search(categoryId, tags, type, page, 10);
	}
	
	public ArrayList<WishEx> search(Long categoryId, ArrayList<Tag> tags, SearchType type, int page, int pageLimit) throws JSONRPCException
	{	
		Session session = Registry.GetSession();
		if(session == null) {
			throw new ApiException("invalid session");
		}
		
		if (pageLimit < 1 || pageLimit > 25) {
			throw new ApiException("invalid pageLimit");
		}
		if (page < 1 || page > 50) {
			throw new ApiException("invalid page");
		}
		
		JSONArray tagsIds = new JSONArray();
		if(tags != null) {
			for(Tag tag : tags) {
				tagsIds.put(tag.getId());
			}
		}
		
		int typeId = 0;
		if(type == SearchType.FRIENDS_ONLY) {
			typeId = 1;
		}

		try {
			ApiResponseArray<WishEx> res =  new ApiResponseArray<WishEx>(GetClient().callJSONObject(
					"wishes.search", session.toObject(), categoryId, tagsIds, typeId, page, pageLimit), WishEx.class);
			
			if(res.getReturnCode() != 0) {
				throw new ApiException("wrong usage: ", res);
			}
			
			return res.getData();
		} catch (JSONException e) {
			throw new ApiException("invalid respond");
		}
	}

	public Wish setWishCanceled(Wish wish) throws JSONRPCException
	{
		try {
			ApiResponseObject<Wish> res =  new ApiResponseObject<Wish>(GetClient().callJSONObject(
					"wishes.setWishCanceled", wish.getId()), Wish.class);
			
			if(res.getReturnCode() != 0) {
				throw new ApiException("wrong usage: ", res);
			}
			
			return res.getData();			
		} catch (JSONException e) {
			throw new ApiException("invalid respond");
		}
	}

}
